package com.ruoyi.course.service.impl;

import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysDictTypeService;

import java.util.*;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.course.dto.CourseDto;
import com.ruoyi.labdata.domain.LabEmployee;
import com.ruoyi.labdata.service.ILabEmployeeService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.course.domain.LabCourse;
import com.ruoyi.course.domain.LabCourseDate;
import com.ruoyi.course.domain.LabCourseTeacher;
import com.ruoyi.course.domain.LabCourseTimetable;
import com.ruoyi.course.mapper.LabCourseDateMapper;
import com.ruoyi.course.mapper.LabCourseMapper;
import com.ruoyi.course.mapper.LabCourseTeacherMapper;
import com.ruoyi.course.service.ILabCourseService;
import com.ruoyi.course.service.ILabCourseTimetableService;
import com.ruoyi.labdata.domain.LabOrgnization;
import com.ruoyi.labdata.service.ILabHolidayReservationService;
import com.ruoyi.labdata.service.ILabOrgnizationService;
import com.ruoyi.synchdata.SynchDataServiceImpl;
import com.ruoyi.system.utils.SysDateUtils;

/**
 * 课程管理Service业务层处理
 *
 * @author jun.wang
 * @date 2022-04-09
 */
@Service
public class LabCourseServiceImpl implements ILabCourseService {
	@Autowired
	private LabCourseMapper labCourseMapper;

	@Autowired
	private LabCourseTeacherMapper labCourseTeacherMapper;

	@Autowired
	private ILabCourseTimetableService labCourseTimetableService;

	@Autowired
	private LabCourseDateMapper labCourseDateMapper;
	
	@Autowired
	private ILabHolidayReservationService reservationService;
	@Autowired
	private ILabOrgnizationService labOrgnizationService;
	@Autowired
	private SynchDataServiceImpl synchDataServiceImpl;
	@Autowired
	private ILabEmployeeService employeeService;
	@Autowired
	private ISysDictTypeService dictTypeService;

	/**
	 * 查询课程管理
	 *
	 * @param courseId
	 *            课程管理ID
	 * @return 课程管理
	 */
	@Override
	public LabCourse selectLabCourseById(Long courseId) {
		LabCourse labCourse = labCourseMapper.selectLabCourseById(courseId);

		LabCourseTeacher query = new LabCourseTeacher();
		query.setCourseId(courseId);
		List<LabCourseTeacher> labCourseTeachers = labCourseTeacherMapper.selectLabCourseTeacherList(query);
		labCourse.setCourseTeacherList(labCourseTeachers);

		return labCourse;
	}

	/**
	 * 查询课程管理列表
	 *
	 * @param labCourse
	 *            课程管理
	 * @return 课程管理
	 */
	@Override
	public List<LabCourse> selectLabCourseList(LabCourse labCourse) {
		return labCourseMapper.selectLabCourseList(labCourse);
	}

	/**
	 * 新增课程管理
	 *
	 * @param labCourse
	 *            课程管理
	 * @return 结果
	 */
	@Override
	@Transactional
	public int insertLabCourse(LabCourse labCourse) {
		labCourse.setCreateTime(DateUtils.getNowDate());
		LabCourseTimetable timeTable = 
				labCourseTimetableService.getDefaultTimetable(labCourse.getCreateTime());
		
		if(timeTable==null){
			throw new RuntimeException("学期日历尚未录入，请先录入日历");
		}
		if(timeTable.getLastDate().before(new Date())){
			throw new RuntimeException("上一个学期日历已经结束，请先录入新的学期日历后再录入新课表");
		}
		/*if(labCourse.getWeekStart()<1 || labCourse.getWeekEnd()<1){
			throw new RuntimeException("周次必须输入正整数");
		}
		if(labCourse.getWeekStart()>labCourse.getWeekEnd()){
			throw new RuntimeException("起始周次必须小于结束周次");
		}*/
		int weeknum = SysDateUtils.getCourseWeekNum(timeTable.getCourseStartDate(), timeTable.getCourseEndDate());
		if(labCourse.getWeekOpenNums()>weeknum){
			throw new RuntimeException("周次必须小于学期最大周数("+weeknum+")");
		}
		labCourse.setTimetableId(timeTable.getTimetableId());
		labCourse.setCreateBy(SecurityUtils.getUsername());

		int i = labCourseMapper.insertLabCourse(labCourse);
		insertCourseTeacher(labCourse);
		List<LabCourseDate> courseDates = labCourseTimetableService.getDates(labCourse);
	    labCourse.setCourseDateList(courseDates);
	    reservationService.doReservation(labCourse);
		insertCourseDate(labCourse);

		return i;
	}

	private void insertCourseDate(LabCourse labCourse) {
		Long courseId = labCourse.getCourseId();
        labCourseDateMapper.deleteLabCourseDateByCourseId(courseId);
        for (LabCourseDate courseDate : labCourse.getCourseDateList()) {
            courseDate.setCourseId(courseId);
            courseDate.setLabId(labCourse.getLabId());
            courseDate.setClassRoomId(labCourse.getClassRoomId());
            if(labCourse.getCourseTeacherList()!=null && labCourse.getCourseTeacherList().size()>0){
            	LabCourseTeacher tearcher = labCourse.getCourseTeacherList().get(0);
            	courseDate.setCreateBy(tearcher.getTeacherNo());
            	courseDate.setNickName(tearcher.getTeacherName());
            }else{
            	courseDate.setCreateBy(labCourse.getCreateBy());
            	courseDate.setNickName(SecurityUtils.getNickName());
            }
            courseDate.setCourseName(labCourse.getCourseName()+"/"+labCourse.getExperimentalProject());
            courseDate.setClassNo(labCourse.getClassNo());
            courseDate.setUserNum(labCourse.getPersonNum());
            courseDate.setWeekNum(labCourse.getWeekOpenNums());
            courseDate.setTimetableId(labCourse.getTimetableId());
            labCourseDateMapper.insertLabCourseDate(courseDate);
        }
       
	}



	private void insertCourseTeacher(LabCourse labCourse) {
		Long courseId = labCourse.getCourseId();
		labCourseTeacherMapper.deleteLabCourseTeacherByCourseId(courseId);
		List<LabCourseTeacher> courseTeacherList = labCourse.getCourseTeacherList();
		for (LabCourseTeacher labCourseTeacher : courseTeacherList) {
			labCourseTeacher.setCourseId(courseId);
			labCourseTeacherMapper.insertLabCourseTeacher(labCourseTeacher);
		}
	}

	/**
	 * 修改课程管理
	 *
	 * @param labCourse
	 *            课程管理
	 * @return 结果
	 */
	@Override
	@Transactional
	public int updateLabCourse(LabCourse labCourse) {
		labCourse.setUpdateTime(DateUtils.getNowDate());
		LabCourseTimetable timeTable = 
				labCourseTimetableService.getDefaultTimetable(labCourse.getUpdateTime());
		
		if(timeTable==null){
			throw new RuntimeException("学期日历尚未录入，请先录入日历");
		}
		LabCourse queryCourse = this.selectLabCourseById(labCourse.getCourseId());
		if(queryCourse.getTimetableId().longValue()!=timeTable.getTimetableId().longValue()){
			throw new RuntimeException("新学期日历已经录入，原课表不能再修改.");
		}
		if(timeTable.getLastDate().before(new Date())){
			throw new RuntimeException("上一个学期日历已经结束，请先录入新的学期日历后再录入新课表");
		}
		int weeknum = SysDateUtils.getCourseWeekNum(timeTable.getCourseStartDate(), timeTable.getCourseEndDate());
		if(labCourse.getWeekOpenNums()>weeknum){
			throw new RuntimeException("周次必须小于学期最大周数("+weeknum+")");
		}
		labCourse.setTimetableId(timeTable.getTimetableId());
		labCourse.setUpdateBy(SecurityUtils.getUsername());
		
		List<LabCourseDate> courseDates = labCourseTimetableService.getDates(labCourse);
	    labCourse.setCourseDateList(courseDates);
		reservationService.cancelReservation(labCourse);
		reservationService.doReservation(labCourse);
		int i = labCourseMapper.updateLabCourse(labCourse);
		insertCourseTeacher(labCourse);
		insertCourseDate(labCourse);
		return i;
	}

	/**
	 * 批量删除课程管理
	 *
	 * @param courseIds
	 *            需要删除的课程管理ID
	 * @return 结果
	 */
	@Override
	@Transactional
	public int deleteLabCourseByIds(Long[] courseIds) {
		for (Long courseId : courseIds) {
			LabCourse labCourse = labCourseMapper.selectLabCourseById(courseId);
			labCourse.setCourseDateList(labCourseTimetableService.getDates(labCourse));
			reservationService.cancelReservation(labCourse);
			labCourseDateMapper.deleteLabCourseDateByCourseId(courseId);
			//labCourseTeacherMapper.deleteLabCourseTeacherByCourseId(courseId);
		}
		
		return labCourseMapper.deleteLabCourseByIds(courseIds);
	}

	/**
	 * 删除课程管理信息
	 *
	 * @param courseId
	 *            课程管理ID
	 * @return 结果
	 */
	@Override
	@Transactional
	public int deleteLabCourseById(Long courseId) {
        labCourseDateMapper.deleteLabCourseDateByCourseId(courseId);
		labCourseTeacherMapper.deleteLabCourseTeacherByCourseId(courseId);
		LabCourse labCourse = labCourseMapper.selectLabCourseById(courseId);
		labCourse.setCourseDateList(labCourseTimetableService.getDates(labCourse));
		reservationService.cancelReservation(labCourse);
		return labCourseMapper.deleteLabCourseById(courseId);
	}

	@Override
	public List<LabCourse> selectLabCourseWeekList(LabCourse labCourse) {
		Date nowDate = DateUtils.getNowDate();
		Calendar instance = Calendar.getInstance();
		instance.setTime(nowDate);
		int dayOfWeek = instance.get(Calendar.DAY_OF_WEEK);
		instance.add(Calendar.DAY_OF_YEAR, -dayOfWeek + 1);
		Date startDate = instance.getTime();
		Date endDate = DateUtils.addDays(startDate, 6);
		labCourse.setStartDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, startDate));
		labCourse.setEndDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, endDate));
		return labCourseMapper.selectLabCourseDateList(labCourse);
	}

	@Override
	public List<LabCourse> selectLabCourseMonthList(LabCourse labCourse) {
		Date nowDate = DateUtils.getNowDate();
		String dataMonthStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM, nowDate);
		String startDate = dataMonthStr + "-01";
		Date nextMonth = DateUtils.addMonths(DateUtils.parseDate(startDate), 1);
		Date endDate = DateUtils.addDays(nextMonth, -1);
		labCourse.setStartDate(startDate);
		labCourse.setEndDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, endDate));
		return labCourseMapper.selectLabCourseDateList(labCourse);
	}

	@Override
	public List<LabCourse> selectLabCourseDateList(LabCourse labCourse) {
		return labCourseMapper.selectLabCourseDateList(labCourse);
	}

	@Override
	public int deleteLabCourseDateById(Long courseDateId) {
		return labCourseDateMapper.deleteLabCourseDateById(courseDateId);
	}

	@Override
	public LabCourse selectLabCourseDateById(Long courseDateId) {

		LabCourse labCourse = labCourseMapper.selectLabCourseByCourseDateId(courseDateId);

		if (labCourse != null) {
			LabCourseTeacher query = new LabCourseTeacher();
			query.setCourseId(labCourse.getCourseId());
			List<LabCourseTeacher> labCourseTeachers = labCourseTeacherMapper.selectLabCourseTeacherList(query);
			labCourse.setCourseTeacherList(labCourseTeachers);
		}

		return labCourse;
	}

	@Override
	public int synchCourseData(Long timetableId) {
		//读取所有部门数据到Map中
		List<LabOrgnization> orgList = labOrgnizationService.selectLabOrgnizationList(new LabOrgnization());
		Map<String, LabOrgnization> orgMap = new HashMap<String, LabOrgnization>();
		orgList.forEach(item ->{
			orgMap.put(item.getOrgName(), item);
		});
		//读取课时表数据
		LabCourseTimetable timeTable = labCourseTimetableService.selectLabCourseTimetableById(timetableId);
		synchDataServiceImpl.synchBKCourse(timetableId, timeTable.getXn(), Integer.valueOf(timeTable.getXq()), orgMap);
		synchDataServiceImpl.synchYJSCourse(timetableId, timeTable.getXn(), Integer.valueOf(timeTable.getXq()), orgMap);
		return 1;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void importData(List<CourseDto> courseDtos, String fileName) {

		String collegeName = StringUtils.substringBefore(fileName, ".");

		LabOrgnization orgQuery = new LabOrgnization();
		orgQuery.setOrgName(collegeName);
		List<LabOrgnization> labOrgnizations = labOrgnizationService.selectLabOrgnizationList(orgQuery);
		if (CollectionUtils.isEmpty(labOrgnizations)) {
			throw new RuntimeException("找不到" + collegeName);
		}
		// 学院ID
		Long collegeOrgId = labOrgnizations.get(0).getOrgId();
		// 专业列表
		List<SysDictData> majorOptList = dictTypeService.selectDictDataByType("majorOpt");
		// 实验室列表
		List<LabOrgnization> labList = labOrgnizationService.listLabBySecondOrgId(collegeOrgId);

		Set<String> errorInfo = new HashSet<>();
		List<LabCourse> labCourseList = new ArrayList<>();
		for (CourseDto courseDto : courseDtos) {
			LabCourse course = new LabCourse();

			// 学院
			course.setCollegeOrgId(collegeOrgId);
			// 专业
			String majorOpt = courseDto.getMajorOpt();
			for (SysDictData item : majorOptList) {
				if (StringUtils.indexOf(item.getDictLabel(), majorOpt) >= 0) {
					course.setMajorOpt(item.getDictValue());
					break;
				}
			}
			// 实验室
			Long labId = null;
			String classRoomId = courseDto.getClassRoomId(); // 开课地点
			for (LabOrgnization lab : labList) {
				if (StringUtils.equals(lab.getOrgName(), classRoomId)) {
					labId = lab.getOrgId();
					break;
				}
			}
			if (labId != null) {
				course.setLabId(labId);
			} else {
				errorInfo.add(classRoomId);
			}

			course.setCourseNo(courseDto.getCourseNo()); // 课程编号
			course.setCourseName(courseDto.getCourseName()); // 课程名称
			course.setExperimentalProject(courseDto.getExperimentalProject()); // 实验项目名称
			course.setExperimentalHours(courseDto.getExperimentalHours()); // 学时
			course.setClassNo(courseDto.getClassNo()); // 班级
			course.setPersonNum(courseDto.getPersonNum()); // 学生人数
			course.setPersonsOfGroup(courseDto.getPersonsOfGroup()); // 每组人数
			course.setClassRoomId(classRoomId); // 开课地点

			List<LabCourseTeacher> teacherList = new ArrayList<>();
			String teacherStr = courseDto.getTeachers();
			String[] teacherArrays = teacherStr.replace("（研究生）", "").split("、");
			for (String t : teacherArrays) {
				LabEmployee query = new LabEmployee();
				query.setEmployeeName(t);
				List<LabEmployee> labEmployees = employeeService.selectLabEmployeeList(query);
				if (CollectionUtils.isNotEmpty(labEmployees)) {
					LabEmployee labEmployee = labEmployees.get(0);
					LabCourseTeacher teacher = new LabCourseTeacher();
					teacher.setTeacherNo(labEmployee.getEmployeeNo());
					teacher.setTeacherName(labEmployee.getEmployeeName());

					teacherList.add(teacher);
				}
			}
			course.setCourseTeacherList(teacherList); // 设置指导老师

			course.setWeekOpenNums(courseDto.getWeekOpenNums()); // 周次

			String day1 = courseDto.getDay1().replace("节", "");
			String day2 = courseDto.getDay2().replace("节", "");
			String day3 = courseDto.getDay3().replace("节", "");
			String day4 = courseDto.getDay4().replace("节", "");
			String day5 = courseDto.getDay5().replace("节", "");
			String day6 = courseDto.getDay6().replace("节", "");
			String day7 = courseDto.getDay7().replace("节", "");
			if (StringUtils.isNotEmpty(day1)) {
				course.setDay1(day1);
			}
			if (StringUtils.isNotEmpty(day2)) {
				course.setDay2(day2);
			}
			if (StringUtils.isNotEmpty(day3)) {
				course.setDay3(day3);
			}
			if (StringUtils.isNotEmpty(day4)) {
				course.setDay4(day4);
			}
			if (StringUtils.isNotEmpty(day5)) {
				course.setDay5(day5);
			}
			if (StringUtils.isNotEmpty(day6)) {
				course.setDay6(day6);
			}
			if (StringUtils.isNotEmpty(day7)) {
				course.setDay7(day7);
			}

			labCourseList.add(course);
		}

		if (errorInfo.size() > 0) {
			StringBuffer sb = new StringBuffer();
			sb.append("实验室：[");
			for (String s : errorInfo) {
				sb.append(s).append(",");
			}
			sb.append("] 未找到");
			throw new RuntimeException(sb.toString());
		}

		for (LabCourse course : labCourseList) {
			insertLabCourse(course);
		}
	}
}
